之前在docker
内使用lumen
的队列服务做了一个异步,处理一些内容审核的相关操作。但是每次重启容器之后都需要进入docker
内部启动lumen
的队列进程(虽然文档内有写使用supervisord
管理进程,但是并没有那么做。。),最近需求上需要使用crontab
,所以决定使用supervisord
来管理这些进程。
supervisord
dockerfile
文件
#安装
RUN apt-get update && apt-get install -y \
supervisor\
cron \
#supervisord
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/supervisord.conf
#crontab
#将root文件添加到 /var/spool/cron/crontabs/ 下
ADD cron/root /var/spool/cron/crontabs/root
#修改root文件的所属组与权限
RUN chown -R root:crontab /var/spool/cron/crontabs/root \
&& chmod 600 /var/spool/cron/crontabs/root
#创建log文件
RUN touch /var/log/cron.log
EXPOSE 80
ENTRYPOINT ["/usr/bin/supervisord","-c", "/etc/supervisor/supervisord.conf"]
注 :ENTRYPOINT
指令需要加-c
的参数,不然会有一个WARNING
supervisord.conf
文件
[supervisord]
nodaemon=true
[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
autostart=true
autorestart=true
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work --daemon --quiet --delay=3 --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=3
redirect_stderr=true
[program:entrypoint]
command=/var/www/html/entrypoint.sh
[program:cron]
command=/etc/init.d/cron start
autostart=true
autorestart=true
redirect_stderr=true
这里有几个需要注意的点:
nodaemon=true
supervisord进程将在前台运行
这里需要为true,不然在启动docker
的时候会出现Exited (0)
,docker
退出的情况。因为镜像的前台必须有东西在跑。
process_name=%(program_name)s_%(process_num)02d
进程namenumprocs=3
指让supervisor运行3进程
在numprocs
为多个的时候process_name
为必须值,不然name会冲突报错
lumen队列
crontab
在上边的dockerfile
文件中已经写了具体安装与配置。
需要注意的是cron
安装之后需要supervisord
启动,然后需要将定时任务条目写在一个root
文件内,在dockerfile
中add
到镜像/var/spool/cron/crontabs/root
目录
* * * * * /usr/local/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
注意: 需要写/usr/local/bin/php
不然会出现任务不执行的情况
此cron 将会每分钟调用一次lumen
命令调度器,当schedule:run
命令执行后,lumen
评估你的调度任务并运行到期的任务。
有可能会遇到任务不执行的情况,需要查看/var/log/cron.log
日志文件,查看具体原因。如果日志文件内没有内容就需要安装rsyslog
,然后修改/etc/rsyslog.conf
文件,将cron.* /var/log/cron.log
前的注释去掉。然后/etc/init.d/rsyslog start
,再次查看cron.log
就可以看到相关日志。
注意:crontab
使用环境变量的问题
由于crontab
的执行机制,所以无法直接使用配置的环境变量,但是我们应用的配置都是通过环境变量来配置的,所以需要通过 env 命令将这些环境变量保存到 /etc/default/locale
里,crontab
在启动时会加载这个文件里的环境变量,否则在执行命令的时候会无法获取相关的应用配置,导致执行错误。所以使用了一个shell
脚本,在supervisord
执行它。
entrypoint.sh
文件
#!/bin/bash
set -x
rm -rf /etc/default/locale
env >> /etc/default/locale
exec "$@"
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。